﻿Imports System.Windows.Media
Imports agsXMPP
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Text
Imports System.IO
Imports System.Windows
Imports System.Media
Imports System.Windows.Media.Animation
Imports System.Globalization







Class MainWindow
    Dim mysBoard As Storyboard
    Public Property chatOpen As Boolean = False
    Public Property ags As New agsXMPP.XmppClientConnection()
    Dim allContacts As New List(Of String)
    Dim contactPrescence As New List(Of String)
    Dim contactShow As New List(Of String)
    Public Property contactsJIDS As New List(Of String)
    Dim contactReources As New List(Of String)
    Public Property contactNicks As New List(Of String)
    Dim indices As New List(Of Integer)
    Public Property fullNames As New List(Of String)
    Dim popupopen As Boolean = False
    Dim locationHash As New Hashtable()
    Dim presHash As New Hashtable()
    Dim tryRecon As Boolean = True





    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles loginButton.Click
        LoginSub()
    End Sub
    Private Sub LoginSub()
        Try
            If Not My.Computer.Registry.CurrentUser.GetSubKeyNames().Contains("Software\ch@tr") Then
                My.Computer.Registry.CurrentUser.CreateSubKey("Software\ch@tr")
            End If
            My.Computer.Registry.CurrentUser.SetValue("Software\ch@tr\password", password.Password)
            If passwordRemember.IsChecked Then
                My.Computer.Registry.CurrentUser.SetValue("Software\ch@tr\user", usernameBox.Text)
            Else
                My.Computer.Registry.CurrentUser.SetValue("Software\ch@tr\user", "")
            End If
            Dim jid As New agsXMPP.Jid(usernameBox.Text)
            ags.Username = jid.User
            ags.Password = password.Password
            ags.Server = jid.Server
            ags.Show = protocol.client.ShowType.dnd
            ags.Status = ""
            ags.Resource = "ch@tr"
            ags.ConnectServer = "talk.google.com"
            ags.AutoResolveConnectServer = False
            ags.AutoRoster = True
            ags.Open()
        Catch ex As Exception
            MessageBox.Show("Login Failed: " + ex.Message)
        End Try
    End Sub
    Private Sub MainWindow_Deactivated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivated
        hidePopup(Me, New System.Windows.Input.MouseEventArgs(Mouse.PrimaryDevice, 10))

    End Sub
    Private Sub authError()
        MessageBox.Show("Your login failed, busta")
        ags.Close()
        tryRecon = False
    End Sub
    Private Sub socketError()
        If LayoutRoot.Dispatcher.Thread.Equals(System.Threading.Thread.CurrentThread) Then
            reconnecting.Visibility = Visibility.Hidden

            VisualStateManager.GoToElementState(LayoutRoot, "login1", True)

        Else
            LayoutRoot.Dispatcher.BeginInvoke(New EventHandler(AddressOf socketError), New Object() {})
            Return
        End If

    End Sub
    Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        AddHandler ags.OnRosterItem, AddressOf RosterItem
        AddHandler ags.OnPresence, AddressOf Presence
        AddHandler ags.OnLogin, AddressOf loggedIn
        AddHandler ags.OnMessage, AddressOf onMessage
        AddHandler ags.OnRosterEnd, AddressOf RosterEnd
        AddHandler ags.OnClose, AddressOf tryReconnect
        AddHandler ags.OnAuthError, AddressOf authError
        AddHandler ags.OnSocketError, AddressOf socketError
        usernameBox.Text = ""
        password.Password = ""
        statusBox.MaxWidth = LayoutRoot.ActualWidth - avatarPIc.ActualWidth - 41
        scrollViewer.MaxHeight = chat.ActualHeight - headerStuff.ActualHeight - 11
        Try
            usernameBox.Text = My.Computer.Registry.CurrentUser.GetValue("Software\ch@tr\user")
        Catch ex As Exception

        End Try
        Try
            passwordRemember.IsChecked = True
            password.Password = My.Computer.Registry.CurrentUser.GetValue("Software\ch@tr\password")
        Catch ex As Exception

        End Try
        If usernameBox.Text <> "" And password.Password <> "" Then
            '  LoginSub()
        End If
        ' Dim t As New tweets()
        't.Show()
    End Sub
    Private Sub tryReconnect(ByVal sender As Object)
        ' ags.Close()
       
        If tryRecon = True Then
            Dim t As New Timers.Timer()
            t.Interval = 20
            t.Start()
            AddHandler t.Elapsed, AddressOf reconnectTimer
        End If

    End Sub
    Private Sub reconnectTimer(ByVal sender As Object, ByVal e As Timers.ElapsedEventArgs)
        DirectCast(sender, Timers.Timer).Stop()
        ' Dim timerInterval = {5, 10, 15, 20, 30, 60}
        If LayoutRoot.Dispatcher.Thread.Equals(System.Threading.Thread.CurrentThread) Then
            reconnecting.Visibility = Visibility.Visible
            Try
                ags.Open()
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        Else
            LayoutRoot.Dispatcher.BeginInvoke(New Timers.ElapsedEventHandler(AddressOf reconnectTimer), New Object() {sender, e})
            Return
        End If
    End Sub
    Private Sub RosterEnd(ByVal sender As Object)
        '  MessageBox.Show("i'm here")
        For Each c In allContacts
            Dim counter As Integer = allContacts.IndexOf(c)
            Dim viq As New agsXMPP.protocol.iq.vcard.VcardIq(protocol.client.IqType.get, New Jid(contactsJIDS(counter)))
            ags.IqGrabber.SendIq(viq, New IqCB(AddressOf VCardResult), Nothing)

        Next
    End Sub
    Private Sub onMessage(ByVal sender As Object, ByVal msg As agsXMPP.protocol.client.Message)
        If LayoutRoot.Dispatcher.Thread.Equals(System.Threading.Thread.CurrentThread) Then

        Else
            LayoutRoot.Dispatcher.BeginInvoke(New agsXMPP.protocol.client.MessageHandler(AddressOf onMessage), New Object() {sender, msg})
            Return
        End If
        Dim a As Application = Application.Current


        If a.windowsOpen Is Nothing Then
            Dim c
            If a.useTabbed = True Then
                c = New chatWindowsTabs()
                c.name = msg.From
                c.Show()
                c.BringIntoView()
                c.Activate()
                c.Focus()
                c.chatBox.Focus()
                c.recMesg(msg)
            Else
                c = New chatwindow()
                c.name = msg.From
                c.Show()
                c.BringIntoView()
                c.Activate()
                c.Focus()
                c.chatBox.Focus()
                c.recMesg(msg)
                c.Topmost = True
            End If
            
        Else
            If a.windowsOpen.Contains(msg.From.Bare.ToLower()) Then
                Dim c
                If a.useTabbed = True Then
                    c = Application.Current.Windows.Item(1)
                Else
                    c = Application.Current.Windows.Item(a.windowsOpen.IndexOf(msg.From.Bare.ToLower()) + 1)
                End If

                c.recMesg(msg)
            Else

                If a.useTabbed = True Then
                    Dim c As chatWindowsTabs = New chatWindowsTabs()
                    c.name = msg.From
                    c.Show()
                    c.BringIntoView()
                    c.Activate()
                    c.Focus()
                    'c.recMesg(msg)
                Else
                    Dim c As chatwindow = New chatwindow()
                    c.name = msg.From
                    c.Show()
                    c.BringIntoView()
                    c.Activate()
                    c.Focus()
                    c.recMesg(msg)
                    c.Topmost = True

                End If
      
            End If
        End If


    End Sub
    Private Sub loggedIn(ByVal sender As Object)
        If LayoutRoot.Dispatcher.Thread.Equals(System.Threading.Thread.CurrentThread) Then
            VisualStateManager.GoToElementState(LayoutRoot, "chat1", True)
            reconnecting.Visibility = Windows.Visibility.Hidden
            contacts.Children.Clear()
            allContacts.Clear()
            contactNicks.Clear()
            contactPrescence.Clear()
            contactReources.Clear()
            contactShow.Clear()
            fullNames.Clear()
            indices.Clear()
            locationHash.Clear()
            presHash.Clear()
            contactsJIDS.Clear()
            ' usernameText.Text = ags.MyJID.Bare
            onlineStatus.SelectedIndex = 1
            statusBorder.BorderBrush = New SolidColorBrush(Colors.Red)
            ags.Show = protocol.client.ShowType.dnd
            ags.Status = "Busy"
            statusBox.Text = "Busy"
            animateStatus()
            ags.SendMyPresence()
            ags.RequestRoster()
            Dim imagebytes As Byte()
            Using ms As New System.IO.MemoryStream()
                imagebytes = ms.ToArray()
            End Using
            Dim v As New agsXMPP.protocol.iq.vcard.VcardIq()
            v.Vcard.Photo = New agsXMPP.protocol.iq.vcard.Photo(New ImageSourceConverter().ConvertToString(avatarPIc.Source))
            Dim p As New agsXMPP.protocol.client.Presence(agsXMPP.protocol.client.ShowType.chat, "ASDF", 5)
            Dim a As New agsXMPP.protocol.x.Avatar()
            a.Hash = agsXMPP.util.Hash.HexToString(imagebytes)
            p.AddChild(a)
            '   ags.Send(v)
            '  ags.Send(p)
        Else
            chat.Dispatcher.BeginInvoke(New ObjectHandler(AddressOf loggedIn), New Object() {sender})
            Return
        End If




    End Sub
    Private Sub UpdateUser(ByVal jid As Jid, ByVal nick As String, ByVal Status As String, ByVal pres As String, ByVal ava As Image)


        If jid.Bare = ags.MyJID.Bare Then
            If pres Is Nothing Then
                If ags.Show = protocol.client.ShowType.away Or ags.Show = protocol.client.ShowType.xa Then
                    pres = "Away"
                ElseIf ags.Show = protocol.client.ShowType.chat Then
                    pres = "Available"
                ElseIf ags.Show = protocol.client.ShowType.dnd Then
                    pres = "Busy"
                ElseIf ags.Show = protocol.client.ShowType.NONE Then
                    pres = contactShow(contactsJIDS.IndexOf(ags.MyJID.Bare.ToLower()))

                End If
            End If
            pres = pres.Replace("Offline/", "")

            If Status Is Nothing Or Status = "" Then
                Status = ags.Status
                If Status Is Nothing Or Status = "" Or Status = "Busy" Or Status = "Available" Or Status = "Away" Or Status = "Invisible" Then
                    Status = pres
                End If

            End If
            ags.Status = Status
            If ava IsNot Nothing Then
                avatarPIc.Source = ava.Source
            End If
            statusBox.Text = Status

            If pres = "Busy" Then
                ags.Show = protocol.client.ShowType.dnd
                statusBorder.BorderBrush = New SolidColorBrush(Colors.Red)
                onlineStatus.SelectedIndex = 1
            ElseIf pres = "Available" Then
                statusBorder.BorderBrush = New SolidColorBrush(Colors.LimeGreen)
                onlineStatus.SelectedIndex = 0
                ags.Show = protocol.client.ShowType.chat
            ElseIf pres = "Away" Then
                statusBorder.BorderBrush = New SolidColorBrush(Colors.Orange)
                ags.Show = protocol.client.ShowType.away
                onlineStatus.SelectedIndex = 2
            ElseIf pres = "Invisible" Then
                onlineStatus.SelectedIndex = 3
                ags.Show = protocol.client.ShowType.NONE
                statusBorder.BorderBrush = New SolidColorBrush(Colors.LightGray)
                Dim p As New protocol.client.Presence()
                p.Type = protocol.client.PresenceType.unavailable
                p.From = ags.MyJID
                p.Show = ags.Show
                ags.Send(p)
            End If
            ags.SendMyPresence()
            animateStatus()
        Else


            Dim counter As Integer = contactsJIDS.IndexOf(jid.Bare)
            Dim index As Integer = indices.Item(counter)
            If index = -1 Then
                'if the user hasn't been added yet, then, well, add them.
                AddContact(jid, nick, Status, pres, ava)
            Else
                'proceed
                If pres Is Nothing Then pres = contactShow(counter)
                If nick Is Nothing Then nick = contactNicks(counter)
                If Status Is Nothing Then Status = contactPrescence(counter)
                If Status Is Nothing Or Status = "" Then Status = pres
                If ava IsNot Nothing Then
                    CType(CType(CType(contacts.Children.Item(index), StackPanel).Children.Item(0), Border).Child, Image).Source = ava.Source
                End If
                If nick Is Nothing Or nick = "" Or nick = jid.User Then
                    nick = fullNames(counter)

                End If
                CType(CType(CType(contacts.Children.Item(index), StackPanel).Children.Item(1), StackPanel).Children.Item(0), TextBlock).Text = nick
                CType(CType(CType(contacts.Children.Item(index), StackPanel).Children.Item(1), StackPanel).Children.Item(1), TextBlock).Text = Status

                Dim avail As New SolidColorBrush()
                If pres = "Busy" Then
                    avail = New SolidColorBrush(Colors.Red)
                ElseIf pres = "Available" Then
                    avail = New SolidColorBrush(Colors.LimeGreen)
                ElseIf pres = "Away" Then
                    avail = New SolidColorBrush(Colors.Orange)
                ElseIf pres = "Offline/Invisible" Then
                    avail = New SolidColorBrush(Colors.LightGray)
                End If
                CType(CType(contacts.Children.Item(index), StackPanel).Children.Item(0), Border).BorderBrush = avail

            End If
        End If
    End Sub
    Private Sub openemail(ByVal sender As Object, ByVal e As RequestNavigateEventArgs)
        Process.Start(New ProcessStartInfo(CType(sender, Hyperlink).NavigateUri.ToString()))
        e.Handled = True

    End Sub
    Private Sub displayPopup(ByVal sender As Object, ByVal e As MouseEventArgs)
        Dim counter = contactsJIDS.IndexOf(CType(sender, StackPanel).Tag)
        popupName.text = fullNames(counter) + " - " + contactShow(counter).Replace("/Invisible", "")
        popupStatus.Text = contactPrescence(counter)
        Dim jid As New Hyperlink()
        jid.Inlines.Add(CType(sender, StackPanel).Tag)
        ' jid.NavigateUri = New System.Uri("MAILTO:" + CType(sender, StackPanel).Tag)

        ' popupJID.Content = jid
        PopupTest.VerticalOffset = CType(sender, StackPanel).ActualHeight * (indices.Item(contactsJIDS.IndexOf(CType(sender, StackPanel).Tag))) + headerStuff.ActualHeight + 20 + 7 * (indices.Item(contactsJIDS.IndexOf(CType(sender, StackPanel).Tag)))
        popupAvatar.Source = CType(CType(CType(contacts.Children.Item(indices(counter)), StackPanel).Children.Item(0), Border).Child, Image).Source
        PopupTest.Placement = Primitives.PlacementMode.Left
        PopupTest.HorizontalOffset = -10
        PopupTest.PlacementTarget = Me
        PopupTest.StaysOpen = True
        ' PopupTest.MaxHeight = 400
        'PopupTest.Width = 260
        PopupTest.IsOpen = True
        CType(sender, StackPanel).Background = New SolidColorBrush(Colors.LightBlue)
        CType(sender, StackPanel).Background.Opacity = 70
        'CType(sender, StackPanel).Focus()
        AddHandler PopupTest.MouseLeave, AddressOf hidePopup
        ' AddHandler jid.RequestNavigate, AddressOf openemail
    End Sub
    Private Sub hidePopup(ByVal sender As Object, ByVal e As MouseEventArgs)
        'PopupTest.IsOpen = False
        If sender.GetType() Is GetType(StackPanel) Then
            CType(sender, StackPanel).Background = New SolidColorBrush(Colors.White)

            Dim x = e.GetPosition(sender).X
            Dim y = e.GetPosition(sender).Y
            Dim top = 0
            Dim bottom = 50
            Dim left = 0
            Dim p As New Point(0, 0)
            If PopupTest.PointToScreen(p).X < PopupTest.PointToScreen(p).X Then
                x = Math.Abs(x)
            End If
            Dim right = CType(sender, StackPanel).ActualWidth + PopupTest.ActualWidth
            If x >= left And x <= right And y >= top And y <= bottom Then

                ' If Not PopupTest.IsMouseCaptured Then
                'PopupTest.IsOpen = False
            Else
                PopupTest.IsOpen = False
                ' MessageBox.Show("sorry, had to leave")
            End If
            ' MessageBox.Show(x.ToString + ", left: " + left.ToString() + ", right: " + right.ToString())



        Else

            PopupTest.IsOpen = False
        End If

    End Sub
    Private Sub showLocations(ByVal sender As Object, ByVal e As MouseEventArgs)
        Try
            Dim h As List(Of String) = locationHash(CType(sender, TextBlock).Tag)
            Dim p As List(Of protocol.client.Presence) = presHash(CType(sender, TextBlock).Tag)
            For Each l As String In h
                Dim location
                If l.StartsWith("Talk") Or l.StartsWith("talk") Then
                    location = "Google Talk"
                ElseIf l.StartsWith("gmail") Then
                    location = "Gmail"
                ElseIf l.StartsWith("android") Then
                    location = "Google Android Mobile Phone"
                ElseIf l.StartsWith("igoogle") Or l.StartsWith("iGoogle") Then
                    location = "iGoogle website"
                Else
                    location = l
                End If
                Dim show As String
                If p(h.IndexOf(l)).Show = protocol.client.ShowType.chat Then
                    show = "Available"
                ElseIf p(h.IndexOf(l)).Show = protocol.client.ShowType.dnd Then
                    show = "Busy"
                ElseIf p(h.IndexOf(l)).Show = protocol.client.ShowType.away Then
                    show = "Away"
                ElseIf p(h.IndexOf(l)).Show = protocol.client.ShowType.xa Then
                    show = "Away"
                ElseIf p(h.IndexOf(l)).Type = protocol.client.PresenceType.available Then
                    show = "Available"
                ElseIf p(h.IndexOf(l)).Type = protocol.client.PresenceType.unavailable Or p(h.IndexOf(l)).Type = protocol.client.PresenceType.invisible Then
                    show = "Offline/Invisble"
                Else
                    show = "Unavailable"
                End If
                MessageBox.Show("Logged in from " + location + " - " + show + " - " + p(h.IndexOf(l)).Status)

            Next
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub
    Private Sub removeFriend(ByVal sender As Object, ByVal e As MouseEventArgs)
        Dim p As New protocol.client.Presence()
        p.To = New Jid(CType(sender, TextBlock).Tag)
        p.Type = protocol.client.PresenceType.unsubscribe
        ags.Send(p)

    End Sub
    Private Sub AddContact(ByVal jid As Jid, ByVal nick As String, ByVal status As String, ByVal pres As String, ByVal ava As Image)
        If jid.Bare = ags.MyJID.Bare Then
            UpdateUser(jid, nick, status, pres, ava)
        Else
            Dim counter As Integer = contactsJIDS.IndexOf(jid.Bare)
            Dim ui As New StackPanel()

            Dim cm As New ContextMenu()
            Dim cmi As New TextBlock()
            cmi.Text = "View logged in locations"
            cmi.Tag = jid.Bare
            AddHandler cmi.MouseLeftButtonUp, AddressOf showLocations
            cm.Items.Add(cmi)
            Dim remove As New TextBlock()
            remove.Text = "Unsubscribe from this contact"
            remove.Tag = jid.Bare
            AddHandler remove.MouseLeftButtonUp, AddressOf removeFriend
            cm.Items.Add(remove)
            ui.ContextMenu = cm
            AddHandler ui.MouseEnter, AddressOf displayPopup
            AddHandler ui.MouseLeave, AddressOf hidePopup
            ui.Cursor = Cursors.Hand
            ui.Focusable = True

            ui.MinWidth = Me.ActualWidth
            ui.Margin = New Thickness(-10, 0, 0, 7)
            ui.HorizontalAlignment = Windows.HorizontalAlignment.Left
            Dim bind As New Binding()
            bind.Source = Me
            ui.SetBinding(StackPanel.WidthProperty, bind)

            ui.Children.Clear()
            ui.Orientation = Orientation.Horizontal
            ui.Width = Me.ActualWidth

            ui.MinHeight = 50
            ui.Background = New SolidColorBrush(Colors.White)
            Dim avatarImage As New Image()
            avatarImage.Margin = New Thickness(5, 0, 15, 0)
            If ava IsNot Nothing Then
                avatarImage = ava
            Else
                avatarImage = New Image()
            End If
            avatarImage.Name = "avatarPic" + contactsJIDS.IndexOf(jid.Bare).ToString()
            Dim b As New Border()

            Dim u As New StackPanel()
            u.Margin = New Thickness(5, 0, 0, 0)
            u.Orientation = Orientation.Vertical
            Dim userT As New TextBlock()
            userT.Name = "Nickname" + counter.ToString()

            userT.Text = nick

            Dim statusT As New TextBlock()
            statusT.Name = "StatusText" + counter.ToString()
            If status Is Nothing Or status = "" Then
                status = pres
            End If
            statusT.Text = status
            statusT.Foreground = New SolidColorBrush(Colors.Gray)

            u.Children.Add(userT)
            u.Children.Add(statusT)
            If pres = "Busy" Then
                b.BorderBrush = New SolidColorBrush(Colors.Red)
            ElseIf pres = "Available" Then
                b.BorderBrush = New SolidColorBrush(Colors.LimeGreen)
            ElseIf pres = "Away" Then
                b.BorderBrush = New SolidColorBrush(Colors.Orange)
            ElseIf pres = "Offline/Invisible" Then
                b.BorderBrush = New SolidColorBrush(Colors.LightGray)
            End If
            b.Margin = New Thickness(15, 0, 0, 0)
            b.BorderThickness = New Thickness(5)
            b.CornerRadius = New CornerRadius(2)
            b.Width = 50
            b.Height = 50
            b.Child = avatarImage
            ui.Children.Add(b)
            ui.Children.Add(u)
            ui.Tag = jid.Bare
            AddHandler ui.MouseLeftButtonDown, AddressOf openChatWindow
            contacts.Children.Add(ui)
            indices.Item(counter) = contacts.Children.IndexOf(ui)

        End If
    End Sub
    Private Sub RosterItem(ByVal sender As Object, ByVal item As agsXMPP.protocol.iq.roster.RosterItem)
        If Not allContacts.Contains(item.Jid.User.ToLower()) Then
            allContacts.Add(item.Jid.User.ToLower())
            contactsJIDS.Add(item.Jid.Bare)
            contactReources.Add(item.Jid.Resource)
            contactShow.Add("Offline/Invisible")
            contactNicks.Add(item.Name)
            contactPrescence.Add("")
            fullNames.Add("")
            indices.Add(-1)

            AddContact(item.Jid, item.Name, "", "Offline/Invisible", Nothing)
            Dim viq As New agsXMPP.protocol.iq.vcard.VcardIq(protocol.client.IqType.get, item.Jid)
            ags.IqGrabber.SendIq(viq, New IqCB(AddressOf VCardResult), Nothing)
            ' ags.RequestRoster()
        Else
            Dim counter As Integer = allContacts.IndexOf(item.Jid.User.ToLower())
            contactNicks.Item(counter) = item.Name
            UpdateUser(item.Jid, item.Name, Nothing, Nothing, Nothing)

        End If
    End Sub
    Private Sub Presence(ByVal sender As Object, ByVal pres As agsXMPP.protocol.client.Presence)
        If LayoutRoot.Dispatcher.Thread.Equals(System.Threading.Thread.CurrentThread) Then

            If Not allContacts.Contains(pres.From.User.ToLower()) Then
                allContacts.Add(pres.From.User.ToLower())
                contactsJIDS.Add(pres.From.Bare)
                contactReources.Add(pres.From.Resource)
                contactNicks.Add("")
                indices.Add(-1)
                fullNames.Add("")
                If pres.Show = protocol.client.ShowType.away Then
                    contactShow.Add("Away")
                ElseIf pres.Show = protocol.client.ShowType.chat Then
                    contactShow.Add("Available")
                ElseIf pres.Show = protocol.client.ShowType.dnd Then
                    contactShow.Add("Busy")
                ElseIf pres.Show = protocol.client.ShowType.NONE Then
                    '  MessageBox.Show(pres.From.Bare + ": " + pres.Type.ToString() + " - " + pres.Show.ToString())

                    If pres.Type = protocol.client.PresenceType.available Then
                        contactShow.Add("Available")
                    Else
                        contactShow.Add("Offline/Invisible")
                    End If
                ElseIf pres.Show = protocol.client.ShowType.xa Then
                    contactShow.Add("Away")
                Else
                    ' MessageBox.Show(pres.From.Bare + ": " + pres.Type.ToString() + " - " + pres.Show.ToString())
                    contactShow.Add("Unavailable")
                End If

                If pres.Status Is Nothing Then pres.Status = ""
                contactPrescence.Add(pres.Status)
                AddContact(pres.From, contactNicks(contactsJIDS.IndexOf(pres.From.Bare)), pres.Status, contactShow.Item(contactsJIDS.IndexOf(pres.From.Bare)), Nothing)
                Dim locationList As New List(Of String)
                Dim presList As New List(Of protocol.client.Presence)
                locationList.Add(pres.From.Resource)
                presList.Add(pres)
                locationHash.Add(pres.From.Bare, locationList)
                presHash.Add(pres.From.Bare, presList)
            Else
                Dim counter As Integer = contactsJIDS.IndexOf(pres.From.Bare)

                If locationHash.ContainsKey(pres.From.Bare) Then
                    Dim locationList As List(Of String) = locationHash(pres.From.Bare)
                    Dim presList As List(Of protocol.client.Presence) = presHash(pres.From.Bare)
                    If locationList.Contains(pres.From.Resource) Then
                        presList(locationList.IndexOf(pres.From.Resource)) = pres
                    Else
                        locationList.Add(pres.From.Resource)
                        presList.Add(pres)
                    End If
                    locationHash(pres.From.Bare) = locationList
                    presHash(pres.From.Bare) = presList
                Else
                    Dim locationList As New List(Of String)
                    Dim presList As New List(Of protocol.client.Presence)
                    locationList.Add(pres.From.Resource)
                    presList.Add(pres)
                    locationHash.Add(pres.From.Bare, locationList)
                    presHash.Add(pres.From.Bare, presList)

                End If
                If contactShow.Item(counter) Is Nothing Or contactShow.Count - 1 < counter Then
                    contactShow.Add("Undefined")
                End If
                If pres.Show = protocol.client.ShowType.away Then
                    contactShow.Item(counter) = "Away"
                ElseIf pres.Show = protocol.client.ShowType.chat Then
                    contactShow.Item(counter) = "Available"
                ElseIf pres.Show = protocol.client.ShowType.dnd Then
                    contactShow.Item(counter) = "Busy"
                ElseIf pres.Show = protocol.client.ShowType.NONE Then

                    '  MessageBox.Show(pres.From.Bare + ": " + pres.Type.ToString() + " - " + pres.Show.ToString())

                    If pres.Type = protocol.client.PresenceType.available Then
                        contactShow.Item(counter) = "Available"
                    Else
                        contactShow.Item(counter) = "Offline/Invisible"
                    End If
                ElseIf pres.Show = protocol.client.ShowType.xa Then
                    contactShow.Item(counter) = "Away"
                Else
                    ' MessageBox.Show(pres.From.Bare + ": " + pres.Type.ToString() + " - " + pres.Show.ToString())

                    contactShow.Item(counter) = "Unavailable"
                End If
                If pres.Status <> "" And pres.Status IsNot Nothing Then
                    contactPrescence.Item(counter) = pres.Status

                End If
                UpdateUser(pres.From, contactNicks(counter), pres.Status, contactShow.Item(counter), Nothing)
            End If
        GetPhoto(pres.From)

        ags.RequestRoster()
        Else
        chat.Dispatcher.BeginInvoke(New agsXMPP.protocol.client.PresenceHandler(AddressOf Presence), New Object() {sender, pres})
        Return
        End If

    End Sub
    Private Sub GetPhoto(ByVal jid As Jid)
        Dim viq As New agsXMPP.protocol.iq.vcard.VcardIq(protocol.client.IqType.get, jid)
        ags.IqGrabber.SendIq(viq, New IqCB(AddressOf VCardResult), Nothing)
    End Sub
    Private Sub VCardResult(ByVal sender As Object, ByVal iq As protocol.client.IQ, ByVal data As Object)
        If LayoutRoot.Dispatcher.Thread.Equals(System.Threading.Thread.CurrentThread) Then
            If iq.Type = protocol.client.IqType.result Then
                Dim vcard As protocol.iq.vcard.Vcard = iq.Vcard
                If vcard IsNot Nothing And iq.From IsNot Nothing Then
                    fullNames(contactsJIDS.IndexOf(iq.From.Bare)) = vcard.Fullname
                    If vcard.Nickname IsNot Nothing And vcard.Nickname <> "" Then
                        contactNicks(contactsJIDS.IndexOf(iq.From.Bare)) = vcard.Nickname
                    End If
                    Dim counter = contactsJIDS.IndexOf(iq.From.Bare)
                    If contactNicks(counter) = allContacts(counter) Or contactNicks(counter) = "" Then
                        contactNicks(counter) = vcard.Fullname
                    End If
                    If vcard.Photo IsNot Nothing Then
                        UpdateUser(iq.From, Nothing, Nothing, Nothing, ToWpfImage(vcard.Photo.Image))
                    Else
                        UpdateUser(iq.From, Nothing, Nothing, Nothing, Nothing)

                    End If
                End If
            End If

        Else
            chat.Dispatcher.BeginInvoke(New IqCB(AddressOf VCardResult), New Object() {sender, iq, data})
            Return
        End If
    End Sub
    Public Shared Function ToWpfImage(ByVal img As System.Drawing.Image) As Image
        Dim ms As New MemoryStream()
        img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp)
        Dim myimage As New Image()

        Using stream As New MemoryStream(ms.ToArray())
            myimage.Source = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad)
        End Using
        myimage.Width = 40
        myimage.Height = 40

        Return (myimage)
    End Function
    Sub openChatWindow(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        Dim t As StackPanel = sender
        Dim m As New agsXMPP.protocol.client.Message()
        m.Body = ""
        m.From = New Jid(t.Tag)
        onMessage(sender, m)
    End Sub
    Private Sub statusBox_GotFocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles statusBox.GotFocus
        mysBoard = New Storyboard()
        NameScope.SetNameScope(headerStuff, New NameScope())

        headerStuff.RegisterName(statusBox.Name, statusBox)
        Dim myDAni As New DoubleAnimation()
        myDAni.From = statusBox.Width
        myDAni.To = statusBox.MaxWidth
        myDAni.Duration = New Duration(TimeSpan.FromMilliseconds(200))
        mysBoard.Children.Add(myDAni)
        Storyboard.SetTargetName(myDAni, statusBox.Name)
        Storyboard.SetTargetProperty(myDAni, New PropertyPath(TextBox.WidthProperty))
        mysBoard.Begin(headerStuff)
        statusBox.SelectAll()
    End Sub
    Private Sub animateStatus()
        mysBoard = New Storyboard()
        NameScope.SetNameScope(headerStuff, New NameScope())

        headerStuff.RegisterName(statusBox.Name, statusBox)
        Dim myDAni As New DoubleAnimation()
        myDAni.From = statusBox.Width
        Dim ft As New FormattedText(statusBox.Text, CultureInfo.GetCultureInfo("en-us"), Windows.FlowDirection.LeftToRight, New Typeface(statusBox.FontFamily.ToString()), statusBox.FontSize, New SolidColorBrush(Colors.Black))
        myDAni.To = ft.Width + 10
        myDAni.Duration = New Duration(TimeSpan.FromMilliseconds(200))
        mysBoard.Children.Add(myDAni)
        Storyboard.SetTargetName(myDAni, statusBox.Name)
        Storyboard.SetTargetProperty(myDAni, New PropertyPath(TextBox.WidthProperty))
        mysBoard.Begin(headerStuff)

    End Sub
    Private Sub statusBox_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Input.KeyEventArgs) Handles statusBox.KeyDown
        If e.Key = Key.Enter Then
            ags.Status = statusBox.Text
            ags.SendMyPresence()
            If statusBox.Text = "" Then
                If ags.Show = protocol.client.ShowType.away Or ags.Show = protocol.client.ShowType.xa Then
                    statusBox.Text = "Away"
                ElseIf ags.Show = protocol.client.ShowType.chat Then
                    statusBox.Text = "Available"
                ElseIf ags.Show = protocol.client.ShowType.dnd Then
                    statusBox.Text = "Busy"
                ElseIf ags.Show = protocol.client.ShowType.NONE Then
                    statusBox.Text = "Available"
                End If
            End If
            statusBox.MoveFocus(New TraversalRequest(FocusNavigationDirection.Next))

        End If
    End Sub
    Private Sub onlineStatus_MouseEnter(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles onlineStatus.MouseEnter
        ' onlineStatus.
    End Sub
    Private Sub onlineStatus_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles onlineStatus.SelectionChanged
        Dim show As Integer = onlineStatus.SelectedIndex
        If show = 0 Then
            ags.Show = protocol.client.ShowType.chat
            ags.SendMyPresence()
            statusBorder.BorderBrush = New SolidColorBrush(Colors.LimeGreen)
        ElseIf show = 1 Then
            ags.Show = protocol.client.ShowType.dnd
            ags.SendMyPresence()
            statusBorder.BorderBrush = New SolidColorBrush(Colors.Red)
        ElseIf show = 2 Then
            ags.Show = protocol.client.ShowType.away
            ags.SendMyPresence()
            statusBorder.BorderBrush = New SolidColorBrush(Colors.Orange)
        ElseIf show = 3 Then
            Dim pres As New agsXMPP.protocol.client.Presence()
            pres.From = ags.MyJID
            pres.Type = protocol.client.PresenceType.unavailable
            ags.Send(pres)
            statusBorder.BorderBrush = New SolidColorBrush(Colors.LightGray)
        End If

    End Sub
    Private Sub MainWindow_LostFocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.LostFocus
        hidePopup(Me, New System.Windows.Input.MouseEventArgs(Mouse.PrimaryDevice, 10))


    End Sub
    Private Sub MainWindow_SizeChanged(ByVal sender As Object, ByVal e As System.Windows.SizeChangedEventArgs) Handles Me.SizeChanged
        statusBox.MaxWidth = LayoutRoot.ActualWidth - avatarPIc.ActualWidth - 43
        scrollViewer.MaxHeight = chat.ActualHeight - headerStuff.ActualHeight - 12
        For Each c In contacts.Children
            CType(c, StackPanel).Width = Me.ActualWidth
        Next

    End Sub
    Private Sub avatarPIc_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles avatarPIc.MouseLeftButtonDown
        Dim o As New Microsoft.Win32.OpenFileDialog()
        o.DefaultExt = ".jpg"
        o.Filter = "Image files|*.jpg; *.png; *.bmp; *.gif"

        Dim result? As Boolean = o.ShowDialog()
        If result = True Then
            avatarPIc.Source = New ImageSourceConverter().ConvertFromString(o.FileName)
            Dim imagebytes As Byte()
            Dim i As System.Drawing.Image = System.Drawing.Image.FromFile(o.FileName.ToLower())

            Dim f As System.Drawing.Imaging.ImageFormat
            Dim h As Integer
            Dim w As Integer
            If 100 * (i.Width / i.Height) > 100 Then
                w = 100
                h = 100 * (i.Height / i.Width)
            Else
                h = 100
                w = 100 * (i.Width / i.Height)
            End If
            '50 * (i.Width / i.Height)
            Dim thumb As New System.Drawing.Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb)

            Using ms As New System.IO.MemoryStream()
                Dim ext As String = Path.GetExtension(o.FileName).ToLower()

                If ext = ".jpg" Or ext = ".jpeg" Then
                    f = System.Drawing.Imaging.ImageFormat.Jpeg
                ElseIf ext = ".bmp" Then
                    f = System.Drawing.Imaging.ImageFormat.Bmp
                ElseIf ext = ".png" Then
                    f = System.Drawing.Imaging.ImageFormat.Png
                ElseIf ext = ".gif" Then
                    f = System.Drawing.Imaging.ImageFormat.Gif
                Else
                    MessageBox.Show("Unsupported file format, please try again")
                    Exit Sub
                End If
                Dim oGraphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(thumb)
                oGraphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed
                oGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed
                oGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low
                Dim rect As New System.Drawing.Rectangle(0, 0, w, h)
                oGraphic.DrawImage(i, rect)
                thumb.Save(ms, f)
                imagebytes = ms.ToArray()
            End Using
            Dim v As New agsXMPP.protocol.iq.vcard.VcardIq()
            v.Vcard.Photo = New agsXMPP.protocol.iq.vcard.Photo(thumb, f)

            v.Type = protocol.client.IqType.set
            Dim p As New agsXMPP.protocol.client.Presence()
            p.Status = ags.Status
            p.Show = ags.Show
            Dim a As New agsXMPP.protocol.x.Avatar()
            a.Hash = agsXMPP.util.Hash.HexToString(imagebytes)
            p.AddChild(a)
            ags.Send(v)
            ags.Send(p)


        End If
    End Sub
    Private Shared Function resizeImage(ByVal imgToResize As System.Drawing.Image, ByVal size As Size) As System.Drawing.Image
        Dim sourceWidth As Integer = imgToResize.Width
        Dim sourceHeight As Integer = imgToResize.Height

        Dim destWidth As Integer = size.Width
        Dim destHeight As Integer = size.Height



        '  Return DirectCast(b, System.Drawing.Image)
    End Function
    Private Sub statusBox_LostFocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles statusBox.LostFocus
        mysBoard = New Storyboard()
        NameScope.SetNameScope(headerStuff, New NameScope())

        headerStuff.RegisterName(statusBox.Name, statusBox)
        Dim myDAni As New DoubleAnimation()
        myDAni.From = statusBox.Width
        Dim ft As New FormattedText(statusBox.Text, CultureInfo.GetCultureInfo("en-us"), Windows.FlowDirection.LeftToRight, New Typeface(statusBox.FontFamily.ToString()), statusBox.FontSize, New SolidColorBrush(Colors.Black))
        myDAni.To = ft.Width + 10


        myDAni.Duration = New Duration(TimeSpan.FromMilliseconds(200))
        mysBoard.Children.Add(myDAni)
        Storyboard.SetTargetName(myDAni, statusBox.Name)
        Storyboard.SetTargetProperty(myDAni, New PropertyPath(TextBox.WidthProperty))
        mysBoard.Begin(headerStuff)
        statusBox.SelectAll()
    End Sub
    Private Sub statusBox_MouseLeftButtonUp(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles statusBox.MouseLeftButtonUp
        statusBox.SelectAll()
    End Sub
End Class
